package com.lihan.GetSeatInLib.Configs;

import java.time.Duration;

import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.jsontype.PolymorphicTypeValidator;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import net.bytebuddy.utility.JavaModule;

@Configuration
public class CustomCacheManagers {
	
	@Bean
	@Primary
	public RedisCacheManager cacheManager(RedisConnectionFactory factory) {
		//缓存保持一小时
		RedisCacheConfiguration config = instanceConfig(60*60);
		return RedisCacheManager.builder(factory).cacheDefaults(config)
				.transactionAware().build();
	}
	
	private RedisCacheConfiguration instanceConfig(long ttl) {
		Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
		ObjectMapper mapper = new ObjectMapper();
		//自定义序列化工具：使用Jackson作为默认序列化工具
		mapper.registerModule(new JavaTimeModule());
		
		mapper.configure(MapperFeature.USE_ANNOTATIONS, true);
		mapper.setSerializationInclusion(Include.ALWAYS);
		mapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,
				ObjectMapper.DefaultTyping.EVERYTHING
				, JsonTypeInfo.As.PROPERTY);
		serializer.setObjectMapper(mapper);
		return RedisCacheConfiguration.defaultCacheConfig().entryTtl(Duration.ofSeconds(ttl))
				//.disableCachingNullValues()
				.serializeValuesWith(RedisSerializationContext.SerializationPair
				.fromSerializer(serializer)
						);
	}

}
